package cn.chiship.framework.docs.biz.service.impl;

import cn.chiship.framework.docs.biz.entity.FileCatalogConfigExample;
import cn.chiship.framework.docs.biz.entity.FileResources;
import cn.chiship.framework.docs.biz.entity.FileResourcesExample;
import cn.chiship.framework.docs.biz.mapper.FileCatalogConfigMapper;
import cn.chiship.framework.docs.biz.mapper.FileResourcesMapper;
import cn.chiship.framework.docs.biz.pojo.dto.FileCatalogChangeStatusDto;
import cn.chiship.framework.docs.biz.service.FileChangeStatusService;
import cn.chiship.framework.docs.core.common.FileCatalogChangeEnum;
import cn.chiship.sdk.core.base.constants.BaseConstants;
import cn.chiship.sdk.core.encryption.Md5Util;
import cn.chiship.sdk.core.id.SnowflakeIdUtil;
import cn.chiship.sdk.core.util.RandomUtil;
import cn.chiship.sdk.framework.util.File2Util;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import cn.chiship.sdk.core.base.BaseResult;
import cn.chiship.sdk.core.enums.BaseResultEnum;
import cn.chiship.sdk.framework.base.BaseServiceImpl;

import cn.chiship.framework.docs.biz.entity.FileCatalogConfig;
import cn.chiship.framework.docs.biz.service.FileCatalogConfigService;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * FileCatalogConfigService实现
 *
 * @author lijian
 * @date 2020/4/23
 */
@Service
public class FileCatalogConfigServiceImpl extends BaseServiceImpl<FileCatalogConfig, FileCatalogConfigExample> implements FileCatalogConfigService {

    private static final Logger LOGGER = LoggerFactory.getLogger(FileCatalogConfigServiceImpl.class);

    @Resource
    FileCatalogConfigMapper fileCatalogConfigMapper;
    @Resource
    private FileChangeStatusService fileChangeStatusService;
    @Resource
    private FileResourcesMapper fileResourcesMapper;

    @Override
    public BaseResult updateByPrimaryKeySelective(FileCatalogConfig fileCatalogConfig) {
        FileCatalogConfigExample fileCatalogConfigExample = new FileCatalogConfigExample();

        FileCatalogConfigExample.Criteria criteria1 = fileCatalogConfigExample.createCriteria();
        criteria1.andCatalogNameEqualTo(fileCatalogConfig.getCatalogName()).andCatalogPidEqualTo(fileCatalogConfig.getCatalogPid()).andIdNotEqualTo(fileCatalogConfig.getId());
        FileCatalogConfigExample.Criteria criteria2 = fileCatalogConfigExample.createCriteria();
        criteria2.andCatalogPathEqualTo(fileCatalogConfig.getCatalogPath()).andCatalogPidEqualTo(fileCatalogConfig.getCatalogPid()).andIdNotEqualTo(fileCatalogConfig.getId());
        fileCatalogConfigExample.or(criteria2);

        List<FileCatalogConfig> fileCatalogConfigs = fileCatalogConfigMapper.selectByExample(fileCatalogConfigExample);
        if (fileCatalogConfigs.isEmpty()) {
            return super.updateByPrimaryKeySelective(fileCatalogConfig);
        } else {
            return BaseResult.error(BaseResultEnum.EXCEPTION_DATA_BASE_REPEAT, "目录名称已存在，请重新输入");
        }
    }

    @Override
    public BaseResult insertSelective(FileCatalogConfig fileCatalogConfig) {
        fileCatalogConfig.setCatalogUuid(RandomUtil.uuidLowerCase());
        fileCatalogConfig.setCatalogType(Byte.valueOf("8"));
        if (fileCatalogConfig.getIsEncryption() == BaseConstants.YES) {
            fileCatalogConfig.setCatalogType(Byte.valueOf("7"));
            fileCatalogConfig.setEncryptionSalt(RandomUtil.uuidLowerCase());
            fileCatalogConfig.setEncryptionPassword(Md5Util.md5(fileCatalogConfig.getEncryptionPassword() + fileCatalogConfig.getEncryptionSalt()));
        }
        fileCatalogConfig.setIsChildren(Byte.parseByte("1"));

        FileCatalogConfigExample fileCatalogConfigExample = new FileCatalogConfigExample();

        FileCatalogConfigExample.Criteria criteria1 = fileCatalogConfigExample.createCriteria();
        criteria1.andCatalogNameEqualTo(fileCatalogConfig.getCatalogName()).andCatalogPidEqualTo(fileCatalogConfig.getCatalogPid());
        FileCatalogConfigExample.Criteria criteria2 = fileCatalogConfigExample.createCriteria();
        criteria2.andCatalogPathEqualTo(fileCatalogConfig.getCatalogPath()).andCatalogPidEqualTo(fileCatalogConfig.getCatalogPid());
        fileCatalogConfigExample.or(criteria2);

        List<FileCatalogConfig> fileCatalogConfigs = fileCatalogConfigMapper.selectByExample(fileCatalogConfigExample);
        if (fileCatalogConfigs.isEmpty()) {
            return super.insertSelective(fileCatalogConfig);
        } else {
            return BaseResult.error(BaseResultEnum.EXCEPTION_DATA_BASE_REPEAT, "目录名称已存在，请重新输入");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResult updateCatalogNameById(FileCatalogConfig fileCatalogConfig, String userId, String userName, String realName) {
        LOGGER.info("开始文件夹重命名业务层");
        fileCatalogConfig.setGmtModified(System.currentTimeMillis());
        //根据id获取文件信息
        FileCatalogConfig fileCatalogConfig2 = fileCatalogConfigMapper.selectByPrimaryKey(fileCatalogConfig.getId());

        FileCatalogConfigExample fileCatalogConfigExample = new FileCatalogConfigExample();
        fileCatalogConfigExample.createCriteria().andCatalogNameEqualTo(fileCatalogConfig.getCatalogName()).andIdNotEqualTo(fileCatalogConfig.getId()).andCatalogPidEqualTo(fileCatalogConfig2.getCatalogPid());
        List<FileCatalogConfig> fileCatalogConfigList = fileCatalogConfigMapper.selectByExample(fileCatalogConfigExample);
        if (!fileCatalogConfigList.isEmpty()) {
            return BaseResult.error(BaseResultEnum.EXCEPTION_DATA_BASE_REPEAT, "文件夹名称已存在，请重新输入");
        }
        int i = fileCatalogConfigMapper.updateByPrimaryKeySelective(fileCatalogConfig);
        if (i <= 0) {
            return BaseResult.error(BaseResultEnum.EXCEPTION_DATA_BASE_UPDATE, null);
        }

        FileCatalogChangeStatusDto fileCatalogChangeStatusDto = new FileCatalogChangeStatusDto();
        fileCatalogChangeStatusDto.setOptionUserId(userId);
        fileCatalogChangeStatusDto.setOptionUserName(userName);
        fileCatalogChangeStatusDto.setOptionRealName(realName);
        fileCatalogChangeStatusDto.setOriginalId(fileCatalogConfig.getId());
        fileCatalogChangeStatusDto.setOriginalName(fileCatalogConfig2.getCatalogName());
        BaseResult baseResult = fileChangeStatusService.saveChange(fileCatalogChangeStatusDto, FileCatalogChangeEnum.RENAME);
        if (!baseResult.isSuccess()) {
            return baseResult;
        }
        LOGGER.info("结束文件夹重命名业务层");
        return baseResult;


    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResult updatePidByIdList(String id, String userId, String userName, String realName) {

        FileCatalogConfig fileCatalogConfig = fileCatalogConfigMapper.selectByPrimaryKey(id);

        if (!fileCatalogConfig.getIsEncryption().equals(BaseConstants.NO) || fileCatalogConfig.getIsAllowDeleted().equals(BaseConstants.NO)) {
            return BaseResult.error(BaseResultEnum.EXCEPTION_DATA_BASE_REPEAT, "不允许删除状态的文件夹与加密文件夹不可删除");
        }
        int delete = fileCatalogConfigMapper.deleteByPrimaryKey(id);
        if (delete <= 0) {
            return BaseResult.error(BaseResultEnum.EXCEPTION_DATA_BASE_DELETE,null);
        }

        //批量修改子文件夹的pid
        FileCatalogConfigExample fileCatalogConfigExample = new FileCatalogConfigExample();
        fileCatalogConfigExample.createCriteria().andIsDeletedEqualTo(BaseConstants.NO).andCatalogPidEqualTo(fileCatalogConfig.getId());
        List<FileCatalogConfig> fileCatalogConfigChildrenList = fileCatalogConfigMapper.selectByExample(fileCatalogConfigExample);
        if (!fileCatalogConfigChildrenList.isEmpty()) {
            List<String> fileCatalogConfigChildrenIdList = fileCatalogConfigChildrenList.stream().map(FileCatalogConfig::getId).collect(Collectors.toList());
            int updatePidByIdList = fileCatalogConfigMapper.updatePidByIdList(fileCatalogConfig.getCatalogPid(), fileCatalogConfigChildrenIdList);
            if (updatePidByIdList <= 0) {
                return BaseResult.error(BaseResultEnum.EXCEPTION_DATA_BASE_DELETE, null);
            }
        }

        //批量修改子文件的pid
        FileResourcesExample fileResourcesExample = new FileResourcesExample();
        fileResourcesExample.createCriteria().andIsDeletedEqualTo(BaseConstants.NO).andCatalogIdEqualTo(fileCatalogConfig.getId());
        List<FileResources> fileResourcesChildrenList = fileResourcesMapper.selectByExample(fileResourcesExample);
        if (!fileResourcesChildrenList.isEmpty()) {
            List<String> fileResourcesChildrenIdList = fileResourcesChildrenList.stream().map(FileResources::getId).collect(Collectors.toList());
            int updatePidByIdList = fileResourcesMapper.updatePidByIdList(fileCatalogConfig.getCatalogPid(), fileResourcesChildrenIdList);
            if (updatePidByIdList <= 0) {
                return BaseResult.error(BaseResultEnum.EXCEPTION_DATA_BASE_DELETE, "系统错误，删除失败");
            }
        }

        FileCatalogChangeStatusDto fileCatalogChangeStatusDto = new FileCatalogChangeStatusDto();
        fileCatalogChangeStatusDto.setOptionUserId(userId);
        fileCatalogChangeStatusDto.setOptionUserName(userName);
        fileCatalogChangeStatusDto.setOptionRealName(realName);
        fileCatalogChangeStatusDto.setOriginalId(fileCatalogConfig.getId());
        fileCatalogChangeStatusDto.setOriginalName(fileCatalogConfig.getCatalogName());
        BaseResult baseResult = fileChangeStatusService.saveChange(fileCatalogChangeStatusDto, FileCatalogChangeEnum.REMOVE_RECYCLE);
        if (!baseResult.isSuccess()) {
            return baseResult;
        }
        return baseResult;

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResult initCatalog(String projectsId) {
        FileCatalogConfigExample fileCatalogConfigExample = new FileCatalogConfigExample();
        fileCatalogConfigExample.createCriteria().andProjectsIdEqualTo(projectsId);
        fileCatalogConfigMapper.deleteByExample(fileCatalogConfigExample);


        FileCatalogConfig fileCatalogConfig = null;

        String data = File2Util.readResourceFile("InitCatalogDatas.json");
        JSONArray firstArray = JSON.parseArray(data);
        for (Integer i = 0; i < firstArray.size(); i++) {
            JSONObject firstJson = firstArray.getJSONObject(i);
            firstJson.put("id", SnowflakeIdUtil.generateStrId());
            firstJson.put("catalogUuid", RandomUtil.uuidLowerCase());
            fileCatalogConfig = JSON.parseObject(firstJson.toJSONString(), FileCatalogConfig.class);
            fileCatalogConfig.setGmtCreated(System.currentTimeMillis());
            fileCatalogConfig.setGmtModified(System.currentTimeMillis());
            fileCatalogConfig.setIsDeleted(Byte.valueOf("0"));
            fileCatalogConfig.setProjectsId(projectsId);
            if (fileCatalogConfig.getIsEncryption() == 1) {
                fileCatalogConfig.setCatalogUuid(RandomUtil.uuidLowerCase());
                fileCatalogConfig.setEncryptionPassword(Md5Util.md5(fileCatalogConfig.getEncryptionPassword() + fileCatalogConfig.getEncryptionSalt()));
            }
            fileCatalogConfigMapper.insertSelective(fileCatalogConfig);
            if (firstJson.containsKey("children")) {
                JSONArray secondArray = firstJson.getJSONArray("children");
                for (Integer j = 0; j < secondArray.size(); j++) {
                    JSONObject secondJson = secondArray.getJSONObject(j);
                    secondJson.put("id", SnowflakeIdUtil.generateStrId());
                    secondJson.put("catalogUuid", RandomUtil.uuidLowerCase());
                    secondJson.put("catalogPid", firstJson.getString("id"));
                    fileCatalogConfig = JSON.parseObject(secondJson.toJSONString(), FileCatalogConfig.class);
                    fileCatalogConfig.setGmtCreated(System.currentTimeMillis());
                    fileCatalogConfig.setGmtModified(System.currentTimeMillis());
                    fileCatalogConfig.setIsDeleted(Byte.valueOf("0"));
                    fileCatalogConfig.setProjectsId(projectsId);
                    fileCatalogConfig.setIsAllowNewFile(Byte.valueOf("1"));
                    fileCatalogConfig.setIsAllowNewFolder(Byte.valueOf("1"));
                    fileCatalogConfig.setIsAllowRead(Byte.valueOf("0"));
                    fileCatalogConfig.setIsAllowDeleted(Byte.valueOf("0"));

                    if (fileCatalogConfig.getIsEncryption() == 1) {
                        fileCatalogConfig.setCatalogUuid(RandomUtil.uuidLowerCase());
                        fileCatalogConfig.setEncryptionPassword(Md5Util.md5(fileCatalogConfig.getEncryptionPassword() + fileCatalogConfig.getEncryptionSalt()));
                    }
                    fileCatalogConfigMapper.insertSelective(fileCatalogConfig);
                }
            }
        }

        return BaseResult.ok(null);
    }
}
